/*****************************************************************************
 *
 * Copyright (c), 2004-2020,ShangHai Neotune Information Technology Co., Ltd.
 *
 * Module Name : snmpdefs.h
 *
 * Author :    sean
 *
 * Date :    2004-02-05
 *
 * Version :    1.00
 *
 * Description :    
 *
 * Other :    
 *
 * Data Structure List: <Main Data Structure>
 *
 * Modification History
 * ---------------------------------------------------------------------------
 *  1: Data :      2004-02-05
 *    Author :     sean
 *    Version :    V100R001M00
 *    Modification : creation
 *
*****************************************************************************/

#if (!defined(snmpdefs_inc))
#define snmpdefs_inc

#ifdef __cplusplus
extern"C" {
#endif

#if (!defined(asn1_inc))
#include "asn1.h"
#endif

#if (!defined(buffer_inc))
#include "buffer_snmp.h"
#endif

#if (!defined(mib_inc))
#include "mib.h"
#endif

#if (!defined(ui64_inc))
#include "ui64.h"
#endif

#if (!defined(vb_inc))
#include "vbdefs.h"
#endif

#if INSTALL_ENVOY_SNMP_VERSION_3
#if (!defined(v3_auth_inc))
#include <v3_auth.h>
#endif

#if (!defined(v3_priv_inc))
#include <v3_priv.h>
#endif
#endif /* #if INSTALL_ENVOY_SNMP_VERSION_3 */

#include "snmpdefs.h"

#define SNMP_VERSION_MIN                0 /* Lower bound for SNMP version */
#define VERSION_RFC1067                 0 /* Classic SNMP */
/* RFC1067, RFC1098, and RFC1157 are equivalent */
#define VERSION_RFC1098                 0
#define VERSION_RFC1157                 0
#define SNMP_VERSION_1                  0 /* now being tagged as version 1 */
#define SNMP_VERSION_2                  1 /* SNMPV2 */
#define SNMP_VERSION_USEC               2 /* User Security option */
#define SNMP_VERSION_3                  3 /* SNMPv3 */
#define SNMP_VERSION_MAX       0x7fffffff /* Upper bound for SNMP version */

/* Define the ports assigned to SNMP for the reception of various types */
/* of packets.                                                          */
#define SNMP_REQUEST_PORT               161
#define SNMP_TRAP_PORT                  1620

#ifdef NEOSNET_STRUCT_ALIGN
#pragma align 1
#endif

/* The following represents a source or destination address in
   a generalized form (which happens to be isomorphic to the
   familiar sockaddr structure found with the socket interface.)
   It is the default Envoy will use for an address structure,
   however it may be overridden by defining ENVOY_SNMPADDR_T. */
struct SNMPADDR_S
        {
        unsigned short  snmp_family;
        bits16_t        snmp_port;
        unsigned char   snmp_data[16];
        };

#ifdef ENVOY_SNMPADDR_T
typedef ENVOY_SNMPADDR_T SNMPADDR_T;
#else
typedef struct SNMPADDR_S SNMPADDR_T;
#endif

/* Typedefs for io and SNMP_ERROR completion routines */
typedef void IO_COMPLETE_T  __((SNMPADDR_T *for_addr, SNMPADDR_T *loc_addr,
                                ptr_t pktp, ALENGTH_T need, ptr_t cookie));
typedef void ERR_COMPLETE_T __((SNMPADDR_T *for_addr, SNMPADDR_T *loc_addr,
                                int error_code, ptr_t cookie));
typedef void RETRANS_CLEANUP_T __((ptr_t cookie));

/* The proxy routine really takes an argument of SNMP_PKT_T *
   but we can't use it as we haven't defined it */
typedef sbits32_t PROXY_ROUTINE_T __(( ));

typedef void AUTH_ROUTINE_T __((OCTET_T *, UINT_16_T, OCTET_T *,
                                UINT_16_T, OCTET_T *));

/* Define the internal representation of an SNMP packet */
typedef struct SNMP_PKT_S
        {
        sbits32_t       snmp_version;
        bits16_t        lcl_ident;      /* Local transaction identifer  */

        char *          user_private;   /* Anything one wants -- but    */
                                        /* remember, if you attach      */
                                        /* something here, you got to   */
                                        /* free it in release_private!! */

        ptr_t           async_cookie;   /* cookie for use with completions */
        IO_COMPLETE_T   *io_complete;    /* Routines to call when processing */
        ERR_COMPLETE_T  *error_complete; /* is complete */
        void (*cont)(struct SNMP_PKT_S *); /* routine to call continue proc */

        SNMPADDR_T      pkt_src;        /* Where this packet came from. */
        SNMPADDR_T      pkt_dst;        /* Where this packet came to.   */

        MIBNODE_T      *mib_root;

        bits32_t        mib_view;       /* Set of mib views which this  */
                                        /* request can see. Use 0xFFFFFFFF */
                                        /* to participate in all views. */

#if (INSTALL_ENVOY_SNMP_RFC1445_VIEWS)
        bits16_t        view_index;     /* view index for use with rfc1445 */
#endif

#if (INSTALL_ENVOY_SNMP_RFC2275_VIEWS)
        EBUFFER_T       view_name;      /* view name for use with rfc2275 */
#endif

#if (INSTALL_ENVOY_SNMP_DYNAMIC_VIEWS)
        struct VIEWINDEX_S *view_family; /* pointer to view family to use */ 
#endif

        EBUFFER_T       community;      /* used for the community string
                                           or context name for v3 */

        bits8_t         flags;          /* See below.                   */
        bits8_t         phase;          /* what phase we are running, should
                                           be the same size as vb_flags */
        ALENGTH_T       maxpkt;         /* the maximum packet we can build */
        ALENGTH_T       buffer_needed;  /* Size of buffer needed   */
        ALENGTH_T       overall_length; /* Message Sequence length */
        ATVALUE_T       pdu_type;
        ALENGTH_T       pdu_length;
        union {
              /* For GetRequest, GetNextRequest,        */
              /* GetResponse, SetRequest,               */
              /* GetBulkRequest, InformRequest,         */
              /* and Trap2 PDUs.                        */

              struct {
                     sbits32_t  request_id;
                     sbits32_t  error_status;
                     sbits32_t  error_index;
                     VBL_T      std_vbl;
                     VBL_T      saved_vbl;
                     sbits32_t  max_reps;
                     int        non_reps;
                     } std_pdu;

#if INSTALL_ENVOY_SNMP_VERSION_1
              /* For Trap PDU   */
              struct {
                     OBJ_ID_T           enterprise_objid;
                     unsigned char      net_address[4];
                     sbits32_t          generic_trap;
                     sbits32_t          specific_trap;
                     bits32_t           trap_time_ticks;
                     VBL_T              trap_vbl;
                     } trap_pdu;
#endif
              } pdu;

        bits8_t         lockflags;
        bits8_t         gate_decr;

#if INSTALL_ENVOY_SNMP_VERSION_3
        sbits32_t       msg_id;
        sbits32_t       msg_max_size;
        bits8_t         msg_flags;
        sbits32_t       msg_sec_model;
        EBUFFER_T       msg_con_id;

        EBUFFER_T       msg_sec_id;
        EBUFFER_T       msg_sec_name;
        sbits32_t       msg_sec_boots;
        sbits32_t       msg_sec_time;
        bits8_t         msg_sec_auth[20];
        bits8_t         msg_sec_priv[20];

        ALENGTH_T       scoped_pdu_length;
        ALENGTH_T       encrypted_pdu_length;
        ALENGTH_T       security_length;
        ALENGTH_T       security_length_2;
        ALENGTH_T       global_length;

        SNMP_AUTH_T    *auth;
        SNMP_PRIV_T    *priv;
#endif

#if INSTALL_ENVOY_SNMP_LOCK
        ENVOY_LOCK_T   *coarse_lock;
#endif

#if INSTALL_ENVOY_AGENTX
        struct ENVOY_AX_PKT_S  *ax_pkt;
        bits32_t                ax_trans_id;
#endif

#if INSTALL_ENVOY_CONTINUE_REENTRANT
        ENVOY_LOCK_T    continue_lock;
#endif

#if INSTALL_ENVOY_EPI_SUB
        bits8_t         sa_opcode2;
        bits8_t         sa_encoding;
#endif

#if INSTALL_ENVOY_SNMP_PROXY
        PROXY_ROUTINE_T *proxy_routine;
#endif
        } SNMP_PKT_T;

#ifdef NEOSNET_STRUCT_ALIGN
#pragma align 0
#endif


/* Values for pdu_type (class and form bits are not included) */
#define GET_REQUEST_PDU                 0
#define GET_NEXT_REQUEST_PDU            1
#define GET_RESPONSE_PDU                2
#define SET_REQUEST_PDU                 3
#define TRAP_PDU                        4
#define GET_BULK_REQUEST_PDU            5
#define INFORM_REQUEST_PDU              6
#define TRAP2_PDU                       7
#define REPORT_PDU                      8
#define MAX_V1_PDU                      4
#define MAX_PDU                         8
#define NO_PDU                       0xFF

/* values for pdu classes in mgt communication class, this is equal
   to 2 to the value of the context tag for the pdu                  */
#define GET_REQUEST_CLASS                 1
#define GET_NEXT_REQUEST_CLASS            2
#define GET_RESPONSE_CLASS                4
#define SET_REQUEST_CLASS                 8
#define TRAP_CLASS                       16
#define GET_BULK_REQUEST_CLASS           32
#define INFORM_REQUEST_CLASS             64
#define TRAP2_CLASS                     128
#define REPORT_CLASS                    256
#define ALL_CLASS                       511

/* Values for error_status      */
//#define NO_ERROR                 0
#define TOO_BIG                  1
#define NO_SUCH_NAME             2
#define BAD_VALUE                3
#define READ_ONLY                4
#define GEN_ERR                  5
#define NO_ACCESS                6
#define WRONG_TYPE               7
#define WRONG_LENGTH             8
#define WRONG_ENCODING           9
#define WRONG_VALUE             10
#define NO_CREATION             11
#define INCONSISTENT_VALUE      12
#define RESOURCE_UNAVAILABLE    13
#define COMMIT_FAILED           14
#define UNDO_FAILED             15
#define AUTHORIZATION_ERROR     16
#define NOT_WRITABLE            17
#define INCONSISTENT_NAME       18
#define LAST_ERROR              19

/* Values for generic_trap      */
#define COLD_START              0
#define WARM_START              1
#define LINK_DOWN               2
#define LINK_UP                 3
#define AUTH_FAILURE            4
#define EGP_NEIGHBOR_LOSS       5
#define ENTERPRISE_SPECIFIC     6

/* For lock flags in the packet structre */
#define LOCK_NOLOCK 0x00
#define LOCK_READ   0x01
#define LOCK_WRITE  0x02

/* Value for message flags in version 3 */
#define ETC_V3_AUTH   0x01
#define ETC_V3_PRIV   0x02
#define ETC_V3_REPORT 0x04

#define ETC_SEC_LEVEL_NONE 0x01
#define ETC_SEC_LEVEL_AUTH 0x02
#define ETC_SEC_LEVEL_PRIV 0x03

/* values for security models */
#define ETC_SEC_MODEL_ANY 0x00
#define ETC_SEC_MODEL_V1  0x01
#define ETC_SEC_MODEL_V2  0x02
#define ETC_SEC_MODEL_USM 0x03
#define ETC_SEC_MODEL_MAX 0x7fffffff

/* values for msgid */
#define ETC_MSGID_MIN 0x00
#define ETC_MSGID_MAX 0x7fffffff        

/* values for mms */
#define ETC_MMS_MIN 0x01e4
#define ETC_MMS_MAX 0x7fffffff
        
/* macros for getting values out of SNMP_PKT_T structure */
#define SNMP_pkt_get_SNMP_version(PKTP) ((PKTP)->snmp_version)
#define SNMP_pkt_get_SNMP_community(PKTP) (&(PKTP)->community)

/* macro to translate a vbp into an index, this is included for
   backwards compatibility, the preferred method is to call
   vbp_to_index directly */
#define VB_TO_INDEX(pkt, vbp)    vbp_to_index(pkt, vbp)
/* Macro to translate a vbp into an index, this is the
   preferred method for customers to do this.  Internally
   Envoy should use the vbp_to_index_error() routine directly. */
#define vbp_to_index(pkt, vbp)   vbp_to_index_error(pkt, vbp, 0)

/* various vb utility routines */
extern  int     vbp_to_index_error  __((SNMP_PKT_T *, VB_T *, int));
extern  VB_T *  index_to_vbp        __((SNMP_PKT_T *, int));
extern  VB_T *  vblp_index_to_vbp   __((VBL_T *, int));

/* Return values from TEST routine */
#define TPROC_GOOD                       0
#define TPROC_NOSUCH                    -1
#define TPROC_GENERR                    -2
#define TPROC_BADVALUE                  -3
#define TPROC_READ_ONLY                 -4
#define TPROC_TOO_BIG                   -5

#define TPROC_NO_ACCESS                 -NO_ACCESS
#define TPROC_WRONG_TYPE                -WRONG_TYPE
#define TPROC_WRONG_LENGTH              -WRONG_LENGTH
#define TPROC_WRONG_ENCODING            -WRONG_ENCODING
#define TPROC_WRONG_VALUE               -WRONG_VALUE
#define TPROC_NO_CREATION               -NO_CREATION
#define TPROC_INCONSISTENT_VALUE        -INCONSISTENT_VALUE
#define TPROC_RESOURCE_UNAVAILABLE      -RESOURCE_UNAVAILABLE
#define TPROC_COMMIT_FAILED             -COMMIT_FAILED
#define TPROC_UNDO_FAILED               -UNDO_FAILED
#define TPROC_AUTHORIZATION_ERROR       -AUTHORIZATION_ERROR
#define TPROC_NOT_WRITABLE              -NOT_WRITABLE
#define TPROC_INCONSISTENT_NAME         -INCONSISTENT_NAME
#define TPROC_LAST_ERROR                -LAST_ERROR

#define TPROC_BADVALUE_INDEX(I)  (I + 1)
#define TPROC_SET_ERROR(P, V, E) ((P)->pdu.std_pdu.error_index = \
                                                (vbp_to_index_error(P, V, 1)),\
                              (P)->pdu.std_pdu.error_status = (sbits32_t)(E),\
                              TPROC_LAST_ERROR)
#define SNMP_ERROR_INDEX(I)     (I + 1)

/* Defines for the security violations in the decode and auth code */
/* Decode first */
#define SNMP_DEC_VIO_UNKNOWN_DST  1
#define SNMP_DEC_VIO_DST_NOTLOCAL 2
#define SNMP_DEC_VIO_UNKNOWN_SRC  3
#define SNMP_DEC_VIO_FAILED_VFY   4
#define SNMP_DEC_VIO_UNKNOWN_CON  5
#define SNMP_DEC_VIO_CON_NOTLOCAL 6
#define SNMP_DEC_VIO_BAD_OPR1     7
#define SNMP_DEC_VIO_BAD_OPR2     8
#define SNMP_DEC_VIO_MAX          8

/* auth next */
#define SNMP_AUTH_VIO_LIFETIME   1
#define SNMP_AUTH_VIO_FAILED_VFY 2

/* Macros to manipulate Integers, Counters, and Gauges. */
/* These assume that these are held as longs.           */
/* Integers are signed, counters and gauges are not.    */
#define inc_integer(I)          ((I)++)
#define dec_integer(I)          ((I)--)
#define add_integer(I,V)        ((I) += (V))
#define sub_integer(I,V)        ((I) -= (V))

/* Counter's can't be decremented */
#define inc_counter(C)          (C++)
#define add_counter(C,V)        (C += (V))

/* Gauges latch at the maximum value */
#define GGMAX   ((bits32_t)0xFFFFFFFF)
#define inc_gauge(G)    ((bits32_t)(G) != GGMAX ? G++ : G)
#define dec_gauge(G)    ((bits32_t)(G) != GGMAX ? G-- : G)
#define add_gauge(G,V)  (G =    \
                        (bits32_t)(V) > (GGMAX - (bits32_t)(G)) ? \
                                GGMAX : \
                                (bits32_t)(G) + (bits32_t)(V))
#define sub_gauge(G,V)  (G -= ((bits32_t)(G) != GGMAX ? (bits32_t)(V) : 0))

/* SNMP_ERROR codes for certain decode routines, other return codes are
   in use by some of the routines so take care when adding to this
   list.  (positive numbers are used by one routine) */
#define DECODE_ASN_PARSE_ERROR      -1
#define DECODE_ALLOCATION_FAILURE   -2
#define DECODE_UNKNOWN_PDU_HANDLERS -3
#define DECODE_UNKNOWN_CONTEXTS     -4

#define SNMP_Decode_Packet(buf, len, saddr, daddr) \
                SNMP_DecodePacketWER(buf, len, saddr, daddr, 0)

extern  void    SNMP_EnvoyInit __((void));

extern  void    SNMP_Continue_function __((SNMP_PKT_T *pktp)); 

extern  void    process_packet_two __((PTR_T dptr));

extern  int     Process_Received_SNMP_Packet __((unsigned char *, int,
                                                 SNMPADDR_T *, SNMPADDR_T *,
                                                 EBUFFER_T *));
extern  void    Process_Rcvd_SNMP_Packet_Async __((size_t, bits8_t *,
                                                   SNMPADDR_T *, SNMPADDR_T *,
                                                   ALENGTH_T, IO_COMPLETE_T *,
                                                   ERR_COMPLETE_T *, ptr_t));
#define SNMP_Continue(PKTP) ((PKTP)->cont(PKTP))

extern  void     Process_Internal_SNMP_Packet   __((SNMP_PKT_T *));

struct LCL_FILE_S;
extern  int      SNMP_DecodePDU   __((SNMP_PKT_T *, struct LCL_FILE_S *));  

extern  SNMP_PKT_T *    SNMP_DecodePacketWER __((unsigned char *, int,
                                                   SNMPADDR_T *, SNMPADDR_T *,
                                                   int *));
extern  SNMP_PKT_T *    SNMP_Allocate        __((void));
extern  void            SNMP_Free            __((SNMP_PKT_T *));
extern  void            Initialize_Pkt       __((SNMP_PKT_T *));

extern  ALENGTH_T       set_pdu_size             __((SNMP_PKT_T *));
extern  void            SNMP_EncodeSnmpNormalPdu   __((SNMP_PKT_T *,
                                                     EBUFFER_T *));
extern  ALENGTH_T       SNMP_Bufsize_For_Packet  __((SNMP_PKT_T *));
extern  int             SNMP_EncodePktWithSiz __((SNMP_PKT_T *,
                                                     EBUFFER_T *,
                                                     ALENGTH_T));
extern  int             SNMP_Encode_Packet   __((SNMP_PKT_T *, EBUFFER_T *));
extern  int             SNMP_Encode_Auth_Msg __((SNMP_PKT_T *, EBUFFER_T *));

#if (INSTALL_ENVOY_SNMP_VERSION_3)
extern  ALENGTH_T       bufsize_for_v3_pkt     __((SNMP_PKT_T *));
extern  void            encode_snmp_scoped_pdu __((SNMP_PKT_T *,
                                                   EBUFFER_T *));
extern  int             encode_snmp_v3         __((SNMP_PKT_T *,
                                                   EBUFFER_T *));
extern  SNMP_PKT_T *    Send_Report_PDU  __((SNMP_PKT_T *, struct LCL_FILE_S *,
                                             bits8_t, OIDC_T *, int,
                                             bits32_t, int *, 
                                             SNMPADDR_T *, SNMPADDR_T *));
struct SNMP_USER_S;
extern  int             decode_scoped_pdu __((SNMP_PKT_T *, 
                                              struct LCL_FILE_S *,
                                              SNMPADDR_T *, SNMPADDR_T *,
                                              ALENGTH_T, 
                                              struct SNMP_USER_S *));

extern  SNMP_PKT_T *    SNMP_Decode_V3_Packet __((SNMP_PKT_T *, 
                                                  struct LCL_FILE_S *,
                                                  SNMPADDR_T *, SNMPADDR_T *,
                                                  ALENGTH_T, int *));

#if (INSTALL_ENVOY_SNMP_V3_TARGET)
extern  int             envoy_add_engine_address __((SNMP_PKT_T *,
                                                     SNMPADDR_T *, int));
#endif /* INSTALL_ENVOY_SNMP_V3_TARGET */
#endif /* INSTALL_ENVOY_SNMP_VERSION_3 */

extern  void            SNMP_Proxy_Request   __((SNMP_PKT_T *));
extern  int             SNMP_Proxy_Response  __((SNMP_PKT_T *));
extern  void            SNMP_Proxy_Traps_And_Reports __((SNMP_PKT_T *));

extern  int             SNMP_Process_Get_PDU  __((SNMP_PKT_T *));

extern  int             SNMP_Process_Test_PDU __((SNMP_PKT_T *));
extern  int             SNMP_Process_Set_PDU  __((SNMP_PKT_T *));

extern  int             SNMP_Process_Next_PDU  __((SNMP_PKT_T *));
extern  int             SNMP_Process_Next_Redo __((SNMP_PKT_T *));
extern  int             SNMP_Process_Bulk_Redo __((SNMP_PKT_T *));

extern  int             SNMP_Process_Finish __((SNMP_PKT_T *, EBUFFER_T *,
                                                ALENGTH_T));

extern  void            ENVOY_Send_SNMP_Packet       __((SNMP_PKT_T *));
extern  void            ENVOY_Send_SNMP_Error_Packet __((SNMP_PKT_T *,
                                                         sbits32_t,
                                                         sbits32_t));

extern  int             scan_vb_for_locator __((SNMP_PKT_T *, int, bits16_t));
extern  int             oidcmp              __((int, OIDC_T *, int, OIDC_T *));
extern  int             SNMP_FindObjectNode    __((VB_T *, SNMP_PKT_T *, int));
extern  int             SNMP_FindNextObject    __((VB_T *, OBJ_ID_T *,
                                                SNMP_PKT_T *, int));

#if INSTALL_ENVOY_SNMP_UTIL_MACROS
#define getproc_started(P, V)   ((V)->vb_flags |= VFLAG_GET_STARTED)
#define getproc_good(P, V)      ((V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_error(P, V, E)  ((P)->pdu.std_pdu.error_status = E, \
                                 (P)->pdu.std_pdu.error_index = \
                                                (vbp_to_index_error(P, V, 1)),\
                                 (V)->vb_flags |= VFLAG_GET_DONE)

#define nextproc_started(P, V)  ((V)->vb_flags |= VFLAG_NEXT_STARTED)
#define nextproc_good(P, V)     ((V)->vb_flags |= VFLAG_NEXT_DONE)
#define nextproc_no_next(P, V)  ((V)->vb_flags |= VFLAG_NEXT_DONE | \
                                                    VFLAG_NEXT_REDO)
#define nextproc_error(P, V, E) ((P)->pdu.std_pdu.error_status = E, \
                                 (P)->pdu.std_pdu.error_index = \
                                                (vbp_to_index_error(P, V, 1)),\
                                 (V)->vb_flags |= VFLAG_NEXT_DONE)

#define getproc_got_int32(P, V, D) ((V)->vb_data_flags_n_type = VT_NUMBER, \
                                    (V)->value_u.v_number = D, \
                                    (V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_got_uint32(P, V, D, T) ((V)->vb_data_flags_n_type = T,\
                                        (V)->value_u.v_counter = D, \
                                        (V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_got_uint64(P, V, D) \
                                ((V)->vb_data_flags_n_type = VT_COUNTER64, \
                                 (V)->value_u.v_counter64.high = (D)->high, \
                                 (V)->value_u.v_counter64.low  = (D)->low, \
                                 (V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_got_uint64_high_low(P, V, H, L) \
                                ((V)->vb_data_flags_n_type = VT_COUNTER64, \
                                 (V)->value_u.v_counter64.high = H, \
                                 (V)->value_u.v_counter64.low  = L, \
                                 (V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_got_ip_address(P, V, D) \
                                ((V)->vb_data_flags_n_type = VT_IPADDRESS, \
                                 MEMCPY(&((V)->value_u.v_network_address), \
                                        &(D), 4), \
                                 (V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_got_empty(P, V) ((V)->vb_data_flags_n_type = VT_EMPTY, \
                                 (V)->vb_flags |= VFLAG_GET_DONE)
#define getproc_got_string(P, V, S, D, F, T) \
                        ((V)->vb_data_flags_n_type = T, \
                         (V)->vb_flags |= VFLAG_GET_DONE, \
                         EBufferPreLoad((F) ? BFL_IS_DYNAMIC : BFL_IS_STATIC,\
                                        &((V)->value_u.v_string), D, S))
#define testproc_started(P, V)  ((V)->vb_flags |= VFLAG_TEST_STARTED)
#define testproc_good(P, V)     ((V)->vb_flags |= VFLAG_TEST_DONE)
#define setproc_started(P, V)   ((V)->vb_flags |= VFLAG_SET_STARTED)
#define setproc_good(P, V)      ((V)->vb_flags |= VFLAG_SET_DONE)
#define setproc_error(P, V, E)  ((P)->pdu.std_pdu.error_status = E,      \
                                 (P)->pdu.std_pdu.error_index = \
                                                (vbp_to_index_error(P, V, 1)),\
                                 (V)->vb_flags |= VFLAG_SET_DONE)
#define undoproc_started(P, V)  ((V)->vb_flags |= VFLAG_UNDO_STARTED)
#define undoproc_good(P, V)     ((V)->vb_flags |= VFLAG_UNDO_DONE)
#define undoproc_error(P, V, E) ((P)->pdu.std_pdu.error_status = E,      \
                                 (P)->pdu.std_pdu.error_index = \
                                                (vbp_to_index_error(P, V, 1)),\
                                 (V)->vb_flags |= VFLAG_UNDO_DONE)
#else /* INSTALL_ENVOY_SNMP_UTIL_MACROS */
void getproc_started            __((SNMP_PKT_T *, VB_T *)); 
void getproc_good               __((SNMP_PKT_T *, VB_T *)); 
void getproc_error              __((SNMP_PKT_T *, VB_T *, INT_32_T)); 
void nextproc_started           __((SNMP_PKT_T *, VB_T *)); 
void nextproc_good              __((SNMP_PKT_T *, VB_T *)); 
void nextproc_no_next           __((SNMP_PKT_T *, VB_T *)); 
void nextproc_error             __((SNMP_PKT_T *, VB_T *, INT_32_T)); 
void testproc_started           __((SNMP_PKT_T *, VB_T *)); 
void testproc_good              __((SNMP_PKT_T *, VB_T *)); 
void setproc_started            __((SNMP_PKT_T *, VB_T *)); 
void setproc_good               __((SNMP_PKT_T *, VB_T *)); 
void setproc_error              __((SNMP_PKT_T *, VB_T *, INT_32_T)); 
void undoproc_started           __((SNMP_PKT_T *, VB_T *)); 
void undoproc_good              __((SNMP_PKT_T *, VB_T *)); 
void undoproc_error             __((SNMP_PKT_T *, VB_T *, INT_32_T)); 

void getproc_got_int32          __((SNMP_PKT_T *, VB_T *, INT_32_T));
void getproc_got_uint32         __((SNMP_PKT_T *, VB_T *, UINT_32_T, OCTET_T));
void getproc_got_ip_address     __((SNMP_PKT_T *, VB_T *, UINT_32_T));
void getproc_got_empty          __((SNMP_PKT_T *, VB_T *));
void getproc_got_string         __((SNMP_PKT_T *, VB_T *, ALENGTH_T,
                                    OCTET_T *, int, OCTET_T));
void getproc_got_uint64          __((SNMP_PKT_T *, VB_T *, UINT_64_T *));
void getproc_got_uint64_high_low __((SNMP_PKT_T *, VB_T *, UINT_32_T,
                                     UINT_32_T));

#endif /* INSTALL_ENVOY_SNMP_UTIL_MACROS */

#define getproc_got_ipaddr(P, V, D) \
                                ((V)->vb_data_flags_n_type = VT_IPADDRESS, \
                                 MEMCPY(&((V)->value_u.v_network_address), \
                                        PTR_IPADDR_BITS(D), 4), \
                                 (V)->vb_flags |= VFLAG_GET_DONE)
#define setproc_all_bits(P, V)  ((V)->vb_flags |= VFLAG_TEST_STARTED |  \
                                                  VFLAG_TEST_DONE |     \
                                                  VFLAG_SET_STARTED |   \
                                                  VFLAG_SET_DONE |      \
                                                  VFLAG_UNDO_STARTED |  \
                                                  VFLAG_UNDO_DONE)
#define undoproc_set(P, V, R)   ((V)->undoproc = (UNDOPROC_T *)(R))
extern void     getproc_nosuchins       __((SNMP_PKT_T *, VB_T *));
extern void     getproc_got_object_id   __((SNMP_PKT_T *, VB_T *, int,
                                            OIDC_T *, int));
extern void     nextproc_next_instance  __((SNMP_PKT_T *, VB_T *, int,
                                            OIDC_T *));
extern void     nextproc_next_instance_string  __((SNMP_PKT_T *, VB_T *,
                                                   ALENGTH_T, bits8_t *, int));
extern void     testproc_tproc_error    __((SNMP_PKT_T *, VB_T *, int));
extern void     testproc_error          __((SNMP_PKT_T *, VB_T *, sbits32_t));


#if (INSTALL_ENVOY_SNMP_SERIALIZE)
typedef void GATE_CONTINUE_T __((ptr_t));

extern int  GateKeeper_Test     __((void));
extern int  GateKeeper_Add      __((sbits16_t, ptr_t, GATE_CONTINUE_T *));
extern void GateRunDeferreds    __((void));
extern void GateDecrement       __((SNMP_PKT_T *));

#define GATE_SNMP     1
#define GATE_SUBAGENT 2

#endif

#if (!defined(auxmth_inc))
#include "auxmth.h"
#endif

extern int std_next __((OIDC_T      lastmastch,
                        int         tcount,
                        OIDC_T     *tlist,
                        OIDC_T     *rlist,
                        char       *cookie,
                        SNMP_PKT_T *pktp));

extern void std_next_async  __((OIDC_T      lastmastch,
                                int         tcount,
                                OIDC_T     *tlist,
                                SNMP_PKT_T *pktp,
                                VB_T       *vbp));

/* We define the following functions for use with the compatibility routines */
extern void async_compat_test __((OIDC_T         lastmatch,
                                  int            tcount,
                                  OIDC_T        *tlist,
                                  SNMP_PKT_T    *pktp,
                                  VB_T          *vbp));

extern void async_compat_get  __((OIDC_T         lastmatch,
                                  int            tcount,
                                  OIDC_T        *tlist,
                                  SNMP_PKT_T    *pktp,
                                  VB_T          *vbp));

extern void async_compat_set  __((OIDC_T         lastmatch,
                                  int            tcount,
                                  OIDC_T        *tlist,
                                  SNMP_PKT_T    *pktp,
                                  VB_T          *vbp));

extern void async_compat_next __((OIDC_T         lastmatch,
                                  int            tcount,
                                  OIDC_T        *tlist,
                                  SNMP_PKT_T    *pktp,
                                  VB_T          *vbp));

extern void async_compat_error __((SNMPADDR_T  *for_addr,
                                   SNMPADDR_T  *loc_addr,
                                   int          ecode,
                                   PTR_T        cookie));

extern void async_compat_io __((SNMPADDR_T  *for_addr,
                                SNMPADDR_T  *loc_addr,
                                PTR_T        pktp,
                                ALENGTH_T    need,
                                PTR_T        cookie));

#ifdef __cplusplus
}
#endif

#endif  /* snmpdefs_inc */
